package interrupt;

public class InstructionList {

    private Instruction[ ] List = {
        new Instruction("ADD", (byte) 0x00, (byte) 1, "ExecuteADD", "DRSR" ,"^[ ]*ADD[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("SUB", (byte) 0x01, (byte) 1, "ExecuteSUB", "DRSR" ,"^[ ]*SUB[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("AND", (byte) 0x02, (byte) 1, "ExecuteAND", "DRSR" ,"^[ ]*AND[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("CMP", (byte) 0x03, (byte) 1, "ExecuteCMP", "DRSR" ,"^[ ]*CMP[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("XOR", (byte) 0x04, (byte) 1, "ExecuteXOR", "DRSR" ,"^[ ]*XOR[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("TEST", (byte) 0x05, (byte) 1, "ExecuteTEST", "DRSR" ,"^[ ]*TEST[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("OR", (byte) 0x06, (byte) 1, "ExecuteOR", "DRSR" ,"^[ ]*OR[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("MVRR", (byte) 0x07, (byte) 1, "ExecuteMVRR", "DRSR" ,"^[ ]*MVRR[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("DEC", (byte) 0x08, (byte) 1, "ExecuteDEC", "DR" ,"^[ ]*DEC[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("INC", (byte) 0x09, (byte) 1, "ExecuteINC", "DR" ,"^[ ]*INC[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("SHL", (byte) 0x0a, (byte) 1, "ExecuteSHL", "DR" ,"^[ ]*SHL[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("SHR", (byte) 0x0b, (byte) 1, "ExecuteSHR", "DR" ,"^[ ]*SHR[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("JR", (byte) 0x41, (byte) 1, "ExecuteJR", "OFFSET" ,"^[ ]*JR[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("JRC", (byte) 0x44, (byte) 1, "ExecuteJRC", "OFFSET" ,"^[ ]*JRC[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("JRNC", (byte) 0x45, (byte) 1, "ExecuteJRNC", "OFFSET" ,"^[ ]*JRNC[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("JRZ", (byte) 0x46, (byte) 1, "ExecuteJRZ", "OFFSET" ,"^[ ]*JRZ[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("JRNZ", (byte) 0x47, (byte) 1, "ExecuteJRNZ", "OFFSET" ,"^[ ]*JRNZ[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("JMPA", (byte) (0x80-256), (byte) 2, "ExecuteJMPA", "ADR" ,"^[ ]*JMPPA[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("LDRR", (byte) (0x81-256), (byte) 1, "ExecuteLDRR", "DRSR" ,"^[ ]*LDRR[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("IN", (byte) (0x82-256), (byte) 1, "ExecuteIN", "IO" ,"^[ ]*IN[ ]+[8A][0-1][ ]*$"),
        new Instruction("STRR", (byte) (0x83-256), (byte) 1, "ExecuteSTRR", "DRSR" ,"^[ ]*STRR[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("PSHF", (byte) (0x84-256), (byte) 1, "ExecutePSHF", "" ,"^[ ]*PSHF[ ]*$"),
        new Instruction("PUSH", (byte) (0x85-256), (byte) 1, "ExecutePUSH", "SR" ,"^[ ]*PUSH[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("OUT", (byte) (0x86-256), (byte) 1, "ExecuteOUT", "IO" ,"^[ ]*OUT[ ]+[8A][0-1][ ]*$[ ]*$"),
        new Instruction("POP", (byte) (0x87-256), (byte) 1, "ExecutePOP", "DR" ,"^[ ]*POP[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("MVRD", (byte) (0x88-256), (byte) 2, "ExecuteMVRD", "DRADR" ,"^[ ]*MVRD[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*[0-9A-F]{1,4}[ ]*$"),
        new Instruction("POPF", (byte) (0x8c-256), (byte) 1, "ExecutePOPF", "" ,"^[ ]*POPF[ ]*$"),
        new Instruction("RET", (byte) (0x8f-256), (byte) 1, "ExecuteRET", "" ,"^[ ]*RET[ ]*$"),
        new Instruction("CALA", (byte) (0xce-256), (byte) 2, "ExecuteCALA", "ADR" ,"^[ ]*CALA[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("ADC", (byte) 0x20, (byte) 1, "ExecuteADC", "DRSR" ,"^[ ]*ADC[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("SBB", (byte) 0x21, (byte) 1, "ExecuteSBB", "DRSR" ,"^[ ]*SBB[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("RCL", (byte) 0x2a, (byte) 1, "ExecuteRCL", "DR" ,"^[ ]*RCL[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("RCR", (byte) 0x2b, (byte) 1, "ExecuteRCR", "DR" ,"^[ ]*RCR[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("ASR", (byte) 0x2c, (byte) 1, "ExecuteASR", "DR" ,"^[ ]*ASR[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("NOT", (byte) 0x2d, (byte) 1, "ExecuteNOT", "DR" ,"^[ ]*NIT[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("JMPR", (byte) 0x60, (byte) 1, "ExecuteJMPR", "SR" ,"^[ ]*JMPR[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("JRS", (byte) 0x64, (byte) 1, "ExecuteJRS", "OFFSET" ,"^[ ]*JRS[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("JRNS", (byte) 0x65, (byte) 1, "ExecuteJRNS", "OFFSET" ,"^[ ]*JRNS[ ]+[0-9A-F]{1,4}[ ]*$"),
        new Instruction("CLC", (byte) 0x6c, (byte) 1, "ExecuteCLC", "" ,"^[ ]*CLC[ ]*$"),
        new Instruction("STC", (byte) 0x6d, (byte) 1, "ExecuteSTC", "" ,"^[ ]*STC[ ]*$"),
        new Instruction("EI", (byte) 0x6e, (byte) 1, "ExecuteEI", "" ,"^[ ]*EI[ ]*$"),
        new Instruction("DI", (byte) 0x6f, (byte) 1, "ExecuteDI", "" ,"^[ ]*DI[ ]*$"),
        new Instruction("CALR", (byte) (0xe0-256), (byte) 1, "ExecuteCALR", "SR" ,"^[ ]*CALR[ ]+R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("LDRA", (byte) (0xe4-256), (byte) 2, "ExecuteLDRA", "DRADR" ,"^[ ]*LDRA[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*[0-9A-F]{1,4}[ ]*$"),
        new Instruction("LDRX", (byte) (0xe5-256), (byte) 2, "ExecuteLDRX", "DRSRADR" ,"^[ ]*LDRX[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*,[ ]*[0-9A-F]{1,4}[ ]*$"),
        new Instruction("STRX", (byte) (0xe6-256), (byte) 2, "ExecuteSTRX", "DRSRADR" ,"^[ ]*STRX[ ]+R([0-9]|[1][0-5])[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*,[ ]*[0-9A-F]{1,4}[ ]*$"),
        new Instruction("STRA", (byte) (0xe7-256), (byte) 2, "ExecuteSTRA", "SRADR" ,"^[ ]*STRA[ ]+,[0-9A-F]{1,4}[ ]*,[ ]*R([0-9]|[1][0-5])[ ]*$"),
        new Instruction("IRET", (byte) (0xef-256), (byte) 1, "ExecuteIRET", "" ,"^[ ]*IRET[ ]*$")};

    public InstructionList() {}
    
    public boolean Competent(String match){
        for (Instruction List1 : this.List) {
            if(match.matches(List1.getMatch())){
                return true;
            }
        }
        return false;
    }
    
    public String getFunc(byte Code){
        for (Instruction List1 : List) {
            if (List1.getCode() == Code) {
                return List1.getFunc();
            }
        }
        System.out.println("Error: Function not found! Code: " + Code);
        return null;
    }
    
    public String getFunc(String Name){
        for (Instruction List1 : List) {
            if (List1.getName().equals(Name)) {
                return List1.getFunc();
            }
        }
        System.out.println("Error: Function not found! Name: " + Name);
        return null;
    }
    
    public byte getCode(String Name){
        for (Instruction List1 : List) {
            if (List1.getName().equals(Name)) {
                return List1.getCode();
            }
        }
        System.out.println("Error: Code not found! Name: " + Name);
        return 0;
    }
    
    public short getSize(String Name){
        for (Instruction List1 : List) {
            if (List1.getName().equals(Name)) {
                return List1.getSize();
            }
        }
        System.out.println("Error: Size not found! Name: " + Name);
        return 0;
    }
    
    public String getName(int Code){
        for(Instruction List1 : List){
            if(List1.getCode() == Code){
                return List1.getName();
            }
        }
        System.out.println("Error: Name not found! Code: " + Code);
        return null;
    }
    
    public String getType(String Name){
        for(Instruction List1 : List){
            if(List1.getName().equals(Name)){
                return List1.getType();
            }
        }
        System.out.println("Error: Type not found! Name: " + Name);
        return null;
    }
    
    public byte getSize(int code){
        for(Instruction List1 : List){
            if(List1.getCode() == code){
                return List1.getSize();
            }
        }
        System.out.println("Error: Size not found! Name: " + code);
        return 0;
    }
}
